/*
 * GeoSystem.cpp
 *
 *  Created on: 22 Aug 2011
 *      Author: Allan
 */

#include "GeoSystem.h"

// C++ includes
#include <algorithm>
#include <cmath>
#include <iostream>
#include <iomanip>

// Boost includes
#include <boost/foreach.hpp>

// GeoReact includes
#include "ElectrolyteSolution.h"
#include "Utils/Algorithms.h"
#include "Utils/SpeciesUtils.h"

GeoSystem::GeoSystem()
{}

GeoSystem::GeoSystem(const Multiphase& multiphase, const ReactionSystem& eReactions) :
multiphase(multiphase), eReactions(eReactions)
{}

GeoSystem::GeoSystem(const Multiphase& multiphase, const ReactionSystem& eReactions, const ReactionSystem& kReactions) :
multiphase(multiphase), eReactions(eReactions), kReactions(kReactions)
{}

void GeoSystem::SetSpeciesPartition(const vector<string>& primarySpecies, const vector<string>& kineticSpecies)
{
	jSpecies = primarySpecies;
	kSpecies = kineticSpecies;
	eSpecies = Difference(multiphase.GetSpecies(), Union(primarySpecies, kineticSpecies));
}

const Multiphase& GeoSystem::GetMultiphase() const
{
	return multiphase;
}

const ReactionSystem& GeoSystem::GetEquilibriumReactions() const
{
	return eReactions;
}

const ReactionSystem& GeoSystem::GetKineticReactions() const
{
	return kReactions;
}

const vector<string>& GeoSystem::GetPrimarySpecies() const
{
	return jSpecies;
}

const vector<string>& GeoSystem::GetEquilibriumSpecies() const
{
	return eSpecies;
}

const vector<string>& GeoSystem::GetKineticSpecies() const
{
	return kSpecies;
}

ostream& operator<<(ostream& out, const GeoSystem& system)
{
	out << "<<<< Multiphase >>>>" << endl;
	out << system.GetMultiphase() << endl;
	
	out << "<<<< Equilibrium-Controlled Reactions >>>>" << endl;
	out << system.GetEquilibriumReactions() << endl;
	
	out << "<<<< Kinetically-Controlled Reactions >>>>" << endl;
	out << system.GetKineticReactions() << endl;
	
	out << "<<<< Primary Species >>>>" << endl;
	BOOST_FOREACH(auto s, system.GetPrimarySpecies())
		out << "(" << system.GetMultiphase()[s] << ") " << s <<  endl;
	
	cout << endl;
	
	out << "<<<< Equilibrium Species >>>>" << endl;
	BOOST_FOREACH(auto s, system.GetEquilibriumSpecies())
		out << "(" << system.GetMultiphase()[s] << ") " << s <<  endl;
	
	cout << endl;
	
	out << "<<<< Kinetic Species >>>>" << endl;
	BOOST_FOREACH(auto s, system.GetKineticSpecies())
		out << "(" << system.GetMultiphase()[s] << ") " << s <<  endl;
	
	return out;
}
